什么是 SQL 的约束?
约束(constraint
)是一种限制,它通过对表的行或列的数据做出限制,来确保表的数据的完整性、唯一性。
约束分为列级约束(对一个数据列创建的约束)和表级约束(对多个数据列创建的约束)。
一般我们在创建数据表的时候都会加入一些约束,如主键约束,非空约束,默认约束。
种类
约束按作用范围可以分为:
约束类型 | 列级约束 | 表级约束 |
---|---|---|
关键字 | NOT NULL 、DEFAULT | UNIQUE 、PRIMARY KEY 、FOREIGN KEY |
当然,上述还可以具体细分为:
约束类型 | 默认约束 | 非空约束 | 主键约束 | 唯一约束 | 外键约束 |
---|---|---|---|---|---|
关键字 | DEFAULT | NOT NULL | PRIMARY KEY | UNIQUE | FOREIGN KEY |
默认约束
默认值约束(DEFAULT
)规定,当有DEFAULT
约束的列,插入数据为空时,将使用默认值。
默认值常用于一些可有可无的字段,比如用户的个性签名,若用户没有设置,系统给他应该设定一个默认的文本,比如空文本或 ‘这个人太懒了,没有留下任何信息’。1
2
3
4
5
6
7
8
9CREATE TABLE user(
username varchar(20) NOT NULL PRIMARY KEY,
password varchar(20) NOT NULL,
usersignature varchar(50) DEFAULT '这个人太懒了,没有留下任何信息'
);
# 正常插入数据
INSERT INTO user(username,password,usersignature) VALUES ('jack','123','天地不仁。。。');
# 插入新数据,usersignature 为空,所以使用默认值
INSERT INTO user(username,password) VALUES ('lucy','123');
输入以下命令1
SELECT * FROM user;
表中usersignature
字段将被 DEFAULT
的默认值 这个人太懒了,没有留下任何信息
填充:
非空约束
非空约束(NOT NULL
),言简意赅,被非空约束的列,在插入值时必须非空。1
2username varchar(20) NOT NULL,
password varchar(20) NOT NULL,
主键约束
主键(PRIMARY KEY
)是用于约束表中的一行,作为这一行的唯一标识符,主键不能有重复记录且不能为空,主键可以设置为一个列或多个列。
- 每张数据表只能有一个主键
- 主键保持记录的唯一性
- 主键自动为
NOT NULL
在数据库中,若有两行记录的数据完全一样,那么如何区分呢?
答案是无法区分,若有两行记录完全相同, MySQL 就会认定它们是同一个实体,这与现实生活是存在差别的。
假如我们要存储一个学生的信息,信息包含姓名,班级,学号,性别,年龄等等。
可学校人这么多,重名的人不知凡几,比如王伟,刘伟。。。因此我们在挑选主键时可以选择学号(大学学号不会重复)来区分不同的学生。1
2
3
4
5
6CREATE TABLE student(
snumber int NOT NULL PRIMARY KEY,
sname varchar(20) NOT NULL,
sclass varchar(20) NOT NULL,
sex int(2) NOT NULL
);
唯一约束
唯一约束(UNIQUE
)规定一张表中指定的一列的值必须不能有重复值,即这一列每个值都是唯一的,和主键约束不同的是它的值可以为NULL
。
举个例子,不同学生的日记写的肯定不一样,要么没做为NULL
,要么做了,但每个人的日记内容肯定不同。这个时候就可以用唯一约束定义日记这份作业了。
1 | CREATE TABLE student( |
外键约束(不建议使用)
外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系。
外键(FOREIGN KEY
)既能确保数据的一致性、完整性,也能表现表与表之间的关系(一对一、一对多)。
一个表可以有多个外键,每个外键必须 REFERENCES
(参考)另一个表的主键,被外键约束的列,取值必须在它参照的列中有对应值。
使用要求
- 数据表的存储引擎必须为 InnoDB ;
- 父表和子表必须使用相同的存储引擎,而且禁止使用临时表;
- 外键列和参照列必须具有相似的数据类型。其中数字的长度或是否有符号为必须相同,而字符的长度可以不同;
- 外键列和参照列必须创建索引。若外键列不存在索引,MySQL 则自动创建索引。
假如现在你是电脑店老板,数据库中有商品表和供货商表,商品表设计时会添加一个指向供货商 id 的外键(该 id 为供货商表的主键),表示这个商品所属的供货商,外键将确保这个外键指向的记录是存在的。
若你尝试删除一个供货商,而该供货商还有商品存在于商品表中,那么操作将无法完成并报错。
为什么会报错呢?
因为你删除了该供货商之后,该供货商的商品还在商品表中,你下次还想进这个商品,找谁?
同理,你在创建一个商品的时候也不能为他指定一个不存在的供货商 id。
1 | # 创建供货商表 |
为什么要用外键?
好处如下:
- 供应商信息不重复,从而不浪费时间和空间;
- 若供应商信息变动,可以只更新
vendors
表中的单个记录,相关表中的数据不用改动; - 由于数据无重复,显然数据是一致的,这使得处理数据更简单。
products
表只存储产品信息,它除了存储供应商 ID(vendors
表的主键)外不存储其他供应商信息。vendors
表的主键又叫作products
的外键, 它将vendors
表与products
表关联,利用供应商 ID 能从vendors
表中找出 相应供应商的详细信息。
注意
约束可以在一个列写完后定义,也可以写完所有列后再定义,如对主键约束而言:1
2
3
4
5
6
7
8
9
10
11
12CREATE TABLE student(
sid int AUTO_INCREMENT PRIMARY KEY,
sname VARCHAR(20) NOT NULL,
sex VARCHAR(20) NOT NULL
)
# 或者
CREATE TABLE student(
sid int AUTO_INCREMENT,
sname VARCHAR(20) NOT NULL,
sex VARCHAR(20) NOT NULL,
PRIMARY KEY(sid)
)
那么,具体在建表时应该如何使用呢?
一般混合使用两者,即非空等约束直接在列后定义,而索引型约束在所有列定义完成后再集中定义,便于查询。
参考
- Ben Forta. MySQL 必知必会 [M]. 人民邮电出版社, 2009
文章信息
时间 | 说明 |
---|---|
2019-02-09 | 初稿 |
2022-08-20 | 微调 |